#import <Foundation/NSArray.h>
#import <Foundation/NSBundle.h>
#import <UIKit/UIHardware.h>
#import <UIKit/UIImage.h>

#import "InputPanel.h"
#import "MousePanel.h"
#import "winuser.h"

@implementation InputPanel

- (id)initWithFrame: (CGRect)frame
{
	self = [super initWithFrame: frame];
	
	delegate = nil;
	
	/* cursor */
	prevPoint = prevP1 = prevP2 = CGPointZero;
	mouseMoved = leftDragging = rightDragging = NO;
	leftClickTimer = rightClickTimer = nil;
	mouseUpTime = gettimeofday_sec();
	
	/* panels */
	panelTimer = nil;
	
	[self setEnabledGestures: 2];
	[self setValue: [NSNumber numberWithBool: NO] forGestureAttribute: 7];
	[self setValue: [NSNumber numberWithBool: NO] forGestureAttribute: 4];
	[self setValue: [NSNumber numberWithBool: YES] forGestureAttribute: 5];
	
	[self setTapDelegate: self];
	
	[panelNum = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num.png"] retain];
	[panelNum0 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_0.png"] retain];
	[panelNum1 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_1.png"] retain];
	[panelNum2 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_2.png"] retain];
	[panelNum3 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_3.png"] retain];
	[panelNum4 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_4.png"] retain];
	[panelNum5 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_5.png"] retain];
	[panelNum6 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_6.png"] retain];
	[panelNum7 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_7.png"] retain];
	[panelNum8 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_8.png"] retain];
	[panelNum9 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_9.png"] retain];
	[panelNumAsterisk = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_Asterisk.png"] retain];
	[panelNumSharp = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Num_Sharp.png"] retain];
	[panelKana = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana.png"] retain];
	[panelKana0 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_0.png"] retain];
	[panelKana1 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_1.png"] retain];
	[panelKana2 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_2.png"] retain];
	[panelKana3 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_3.png"] retain];
	[panelKana4 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_4.png"] retain];
	[panelKana5 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_5.png"] retain];
	[panelKana6 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_6.png"] retain];
	[panelKana7 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_7.png"] retain];
	[panelKana8 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_8.png"] retain];
	[panelKana9 = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_9.png"] retain];
	[panelKanaAsterisk = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_Asterisk.png"] retain];
	[panelKanaSharp = [UIImage imageAtPath: @"/private/var/mobile/Library/TouchRemocon/JapaneseInput/JapaneseInput_Kana_Sharp.png"] retain];
	
	[self setImage: panelNum];
	
	currentMode = Mode_Num;
	
	return self;
}

- (void)dealloc
{
	[panelKana release];
	[panelKana0 release];
	[panelKana1 release];
	[panelKana2 release];
	[panelKana3 release];
	[panelKana4 release];
	[panelKana5 release];
	[panelKana6 release];
	[panelKana7 release];
	[panelKana8 release];
	[panelKana9 release];
	[panelKanaAsterisk release];
	[panelKanaSharp release];
	[panelNum release];
	[panelNum0 release];
	[panelNum1 release];
	[panelNum2 release];
	[panelNum3 release];
	[panelNum4 release];
	[panelNum5 release];
	[panelNum6 release];
	[panelNum7 release];
	[panelNum8 release];
	[panelNum9 release];
	[panelNumAsterisk release];
	[panelNumSharp release];
}

- (void)setDelegate: (id)d
{
	delegate = d;
}

- (id)delegate
{
	return delegate;
}

- (int)toggleMode
{
	switch (currentMode)
	{
		case Mode_Num:
			currentMode = Mode_Kana;
			[self setImage: panelKana];
			break;
		
		case Mode_Kana:
			currentMode = Mode_Num;
			[self setImage: panelNum];
			break;
	}
	
	return currentMode;
}

- (int)cellIDByPoint: (CGPoint)p
{
	return (((int)p.y - 140) / 64 * 5) + ((int)p.x / 64);	// 140 = 480 - 20 - (64 * 5)
}

- (void)mouseDown: (GSEventRef)e
{
	CGPoint p = GSEventGetLocationInWindow(e).origin;
	// NSLog(@"down: (%f, %f)", p.x, p.y);
	
	/* マウスカーソル操作 */
	if (p.y < 140)
	{
		cursorOperation = true;
		
		// クリックが発生前ならば、左ドラッグ開始
		if (leftClickTimer && [leftClickTimer isValid])
		{
			[leftClickTimer invalidate];
			
			[delegate mouseLeftButtonPress];
			leftDragging = YES;
		}
		
		mouseDownPoint = prevPoint = p;
		mouseDownTime = gettimeofday_sec();
		
		return;
	}
	
	cursorOperation = false;
	pressedKey = -1;
	
	/*
		ID:
		+-+-+-+-+-+
		| | | | | |  0  1  2  3  4
		+-+-+-+-+-+
		|S|1|2|3|B|  5  6  7  8  9
		+p+-+-+-+ +
		|c|4|5|6|S| 10 11 12 13 14
		+-+-+-+-+-+
		| |7|8|9|E| 15 16 17 18 19
		+-+-+-+-+n+
		| |*|0|#|t| 20 21 22 23 24
		+-+-+-+-+-+
		
		@todo: HP電卓式: 数値キーはそのままのID, 他は行 + 列の2桁ID
	*/
	int cell = [self cellIDByPoint: p];
	
	if (currentMode == Mode_Num)	// switch? if?
	{
		[panelTimer release];
		panelTimer = nil;
		
		switch (cell)
		{
			case 5:
			case 10:
				[delegate keyClicked: VK_SPACE];	break;
			case 6:	// 1
				pressedKey = Key_1;	break;
			case 7:	// 2
				pressedKey = Key_2;	break;
			case 8:	// 3
				pressedKey = Key_3;	break;
			case 9:
			case 14:
				[delegate keyClicked: VK_BACK];	break;
			case 11:	// 4
				pressedKey = Key_4;	break;
			case 12:	// 5
				pressedKey = Key_5;	break;
			case 13:	// 6
				pressedKey = Key_6;	break;
			case 15:	// 123/かな
				[self toggleMode];	break;
			case 16:	// 7
				pressedKey = Key_7;	break;
			case 17:	// 8
				pressedKey = Key_8;	break;
			case 18:	// 9
				pressedKey = Key_9;	break;
			case 19:
			case 24:
				[delegate keyClicked: VK_RETURN];	break;
			case 20:	// 変換
				[delegate keyClicked: VK_OEM_AUTO];	break;
			case 21:	// *
				pressedKey = Key_Asterisk;	break;
			case 22:	// 0
				pressedKey = Key_0;	break;
			case 23:	// #
				pressedKey = Key_Sharp;	break;
		}
	}
	else if (currentMode == Mode_Kana)
	{
		switch (cell)
		{
			case 5:
			case 10:
				[delegate keyClicked: VK_SPACE];	break;
			case 6:	// 1
				pressedKey = Key_1;	break;
			case 7:	// 2
				pressedKey = Key_2;	break;
			case 8:	// 3
				pressedKey = Key_3;	break;
			case 9:
			case 14:
				[delegate keyClicked: VK_BACK];	break;
			case 11:	// 4
				pressedKey = Key_4;	break;
			case 12:	// 5
				pressedKey = Key_5;	break;
			case 13:	// 6
				pressedKey = Key_6;	break;
			case 15:	// 123/かな
				[self toggleMode];	break;
			case 16:	// 7
				pressedKey = Key_7;	break;
			case 17:	// 8
				pressedKey = Key_8;	break;
			case 18:	// 9
				pressedKey = Key_9;	break;
			case 19:
			case 24:
				[delegate keyClicked: VK_RETURN];	break;
			case 20:	// 変換
				[delegate keyClicked: VK_OEM_AUTO];	break;
			case 21:	// *
				pressedKey = Key_Asterisk;	break;
			case 22:	// 0
				pressedKey = Key_0;	break;
			case 23:	// #
				pressedKey = Key_Sharp;	break;
		}
	}
	
	/*
		数字キーの場合は一定時間経過後に入力ボタンを展開(画像を変更)
	*/
	switch (cell)
	{
		case 6:	// 1
		case 7:	// 2
		case 8:	// 3
		case 11:	// 4
		case 12:	// 5
		case 13:	// 6
		case 16:	// 7
		case 17:	// 8
		case 18:	// 9
		case 21:	// *
		case 22:	// 0
		case 23:	// #
			[panelTimer = [NSTimer scheduledTimerWithTimeInterval: PANEL_SHOW_DELAY target: self selector: @selector(showPanel:) userInfo: nil repeats: NO] retain];
			break;
	}
}

- (void)mouseDragged: (GSEventRef)event
{
	if (!cursorOperation)	return;
	
	CGSize screen = [UIHardware fullScreenApplicationContentRect].size;
	CGPoint p = GSEventGetLocationInWindow(event).origin;
	
	int x = (int)(p.x / screen.width * USHRT_MAX);
	int y = (int)(p.y / screen.height * USHRT_MAX);
	
	[delegate mouseMoveAbsolute: CGPointMake(x, y)];
	[delegate mouseMoveRelative: CGPointMake(p.x - prevPoint.x, p.y - prevPoint.y)];
	
	prevPoint = p;
}

- (void)mouseUp: (GSEventRef)e
{
	CGPoint p = GSEventGetLocationInWindow(e).origin;
	
	if (cursorOperation)
	{
		double prevMouseUpTime = mouseUpTime;
		mouseUpTime = gettimeofday_sec();
		
		// double click
		if (!mouseMoved && (gettimeofday_sec() - prevMouseUpTime) < (CLICK_TIMEOUT / 1000.0) && diffLength(&p, &mouseDownPoint) < SAME_POINT_MARGIN)
		{
			if (!leftDragging)
				[delegate mouseLeftButtonPress];
			[delegate mouseLeftButtonRelease];
			leftDragging = NO;
			[delegate mouseLeftButtonClick];
			return;
		}
		
		// 今回のマウスイベントがカーソル移動だったらYES
		mouseMoved = ((SAME_POINT_MARGIN < diffLength(&p, &mouseDownPoint)) ? YES : NO);
		
		// 左ドラッグ中だった場合、ドラッグを終了
		if (leftDragging)
		{
			[delegate mouseLeftButtonRelease];
			leftDragging = NO;
			return;
		}
		
		// single click
		if (diffLength(&p, &mouseDownPoint) < SAME_POINT_MARGIN && (gettimeofday_sec() - mouseDownTime) < (CLICK_INTERVAL / 1000.0))
		{
			[leftClickTimer release];
			leftClickTimer = [NSTimer scheduledTimerWithTimeInterval: (CLICK_TIMEOUT / 1000.0) target: self selector: @selector(sendMouseLeftButtonClick:) userInfo: nil repeats: NO];
			[leftClickTimer retain];
		}
		
		return;
	}
	
	
	if (panelTimer && [panelTimer isValid])
		[panelTimer invalidate];
	
	/*
		ID:
		+-+-+-+-+-+
		| | | | | |  0  1  2  3  4
		+-+-+-+-+-+
		|S|1|2|3|B|  5  6  7  8  9
		+p+-+-+-+ +
		|c|4|5|6|S| 10 11 12 13 14
		+-+-+-+-+-+
		| |7|8|9|E| 15 16 17 18 19
		+-+-+-+-+n+
		| |*|0|#|t| 20 21 22 23 24
		+-+-+-+-+-+
		
		@todo: HP電卓式: 数値キーはそのままのID, 他は行 + 列の2桁ID
	*/
	int cell = [self cellIDByPoint: p];
	
	if (currentMode == Mode_Num)	// switch? if?
	{
		switch (cell)
		{
			case 5:
				switch (pressedKey)
				{
					case Key_1:
						[delegate keyClicked: VK_OEM_3];	break;
				}
				break;
			case 6:	// 1
				switch (pressedKey)
				{
					case Key_1:
						[delegate keyClicked: prevChar[0] = '1'];	break;
					case Key_2:
						[delegate keyClicked: prevChar[0] = 'A'];	break;
				}
				break;
			case 7:	// 2
				switch (pressedKey)
				{
					case Key_1:
						[delegate keyClicked: VK_OEM_2];	break;
					case Key_2:
						[delegate keyClicked: prevChar[0] = '2'];	break;
					case Key_3:
						[delegate keyClicked: prevChar[0] = 'D'];	break;
				}
				break;
			case 8:	// 3
				switch (pressedKey)
				{
					case Key_2:
						[delegate keyClicked: prevChar[0] = 'C'];	break;
					case Key_3:
						[delegate keyClicked: prevChar[0] = '3'];	break;
				}
				break;
			case 9:
				switch (pressedKey)
				{
					case Key_3:
						[delegate keyClicked: prevChar[0] = 'F'];	break;
				}
				break;
			case 10:
				switch (pressedKey)
				{
					case Key_4:
						[delegate keyClicked: prevChar[0] = 'G'];	break;
				}
				break;
			case 11:	// 4
				switch (pressedKey)
				{
					case Key_1:
						[delegate keyClicked: VK_OEM_PERIOD];	break;
					case Key_4:
						[delegate keyClicked: prevChar[0] = '4'];	break;
					case Key_5:
						[delegate keyClicked: prevChar[0] = 'J'];	break;
				}
				break;
			case 12:	// 5
				switch (pressedKey)
				{
					case Key_2:
						[delegate keyClicked: prevChar[0] = 'B'];	break;
					case Key_4:
						[delegate keyClicked: prevChar[0] = 'I'];	break;
					case Key_5:
						[delegate keyClicked: prevChar[0] = '5'];	break;
					case Key_6:
						[delegate keyClicked: prevChar[0] = 'M'];	break;
				}
				break;
			case 13:	// 6
				switch (pressedKey)
				{
					case Key_3:
						[delegate keyClicked: prevChar[0] = 'E'];	break;
					case Key_5:
						[delegate keyClicked: prevChar[0] = 'L'];	break;
					case Key_6:
						[delegate keyClicked: prevChar[0] = '6'];	break;
				}
				break;
			case 14:
				switch (pressedKey)
				{
					case Key_6:
						[delegate keyClicked: prevChar[0] = 'O'];	break;
				}
				break;
			case 15:	// 123/かな
				switch (pressedKey)
				{
					case Key_7:
						[delegate keyClicked: prevChar[0] = 'P'];	break;
				}
				break;
			case 16:	// 7
				switch (pressedKey)
				{
					case Key_4:
						[delegate keyClicked: prevChar[0] = 'G'];	break;
					case Key_7:
						[delegate keyClicked: prevChar[0] = '7'];	break;
					case Key_8:
						[delegate keyClicked: prevChar[0] = 'S'];	break;
				}
				break;
			case 17:	// 8
				switch (pressedKey)
				{
					case Key_5:
						[delegate keyClicked: prevChar[0] = 'K'];	break;
					case Key_7:
						[delegate keyClicked: prevChar[0] = 'R'];	break;
					case Key_8:
						[delegate keyClicked: prevChar[0] = '8'];	break;
					case Key_9:
						[delegate keyClicked: prevChar[0] = 'V'];	break;
				}
				break;
			case 18:	// 9
				switch (pressedKey)
				{
					case Key_6:
						[delegate keyClicked: prevChar[0] = 'N'];	break;
					case Key_8:
						[delegate keyClicked: prevChar[0] = 'U'];	break;
					case Key_9:
						[delegate keyClicked: prevChar[0] = '9'];	break;
				}
				break;
			case 19:
				switch (pressedKey)
				{
					case Key_9:
						[delegate keyClicked: prevChar[0] = 'X'];	break;
				}
				break;
			case 20:	// 変換
				switch (pressedKey)
				{
					case Key_Asterisk:
						break;
				}
				break;
			case 21:	// *
				switch (pressedKey)
				{
					case Key_7:
						[delegate keyClicked: prevChar[0] = 'Q'];	break;
					case Key_Asterisk:
						[delegate keyClicked: VK_MULTIPLY];	break;
					case Key_0:
						[delegate keyClicked: prevChar[0] = 'Y'];	break;
				}
				break;
			case 22:	// 0
				switch (pressedKey)
				{
					case Key_8:
						[delegate keyClicked: prevChar[0] = 'T'];	break;
					case Key_Asterisk:
						break;
					case Key_0:
						[delegate keyClicked: prevChar[0] = '0'];	break;
					case Key_Sharp:
						break;
				}
				break;
			case 23:	// #
				switch (pressedKey)
				{
					case Key_9:
						[delegate keyClicked: prevChar[0] = 'W'];	break;
					case Key_0:
						[delegate keyClicked: prevChar[0] = 'Z'];	break;
					case Key_Sharp:
						[delegate keyPressed: VK_SHIFT];
						[delegate keyClicked: prevChar[0] = '3'];
						[delegate keyReleased: VK_SHIFT];
						break;
				}
				break;
			case 24:
				switch (pressedKey)
				{
					case Key_Sharp:
						break;
				}
				break;
		}
		
		[self setImage: panelNum];
	}
	else if (currentMode == Mode_Kana)
	{
		switch (cell)
		{
			case 1:
				switch (pressedKey)
				{
					case Key_1:
						[delegate keyClicked: prevChar[0] = 'U'];	break;
				}
				break;
			case 2:
				switch (pressedKey)
				{
					case Key_2:
						[delegate keyClicked: prevChar[0] = 'K'];	[delegate keyClicked: prevChar[1] = 'U'];	break;
				}
				break;
			case 3:
				switch (pressedKey)
				{
					case Key_3:
						[delegate keyClicked: prevChar[0] = 'S'];	[delegate keyClicked: prevChar[1] = 'U'];	break;
				}
				break;
			case 5:
				switch (pressedKey)
				{
					case Key_1:
						[delegate keyClicked: prevChar[0] = 'I'];	break;
				}
				break;
			case 6:	// 1
				switch (pressedKey)
				{
					case Key_1:
						[delegate keyClicked: prevChar[0] = 'A'];	break;
					case Key_2:
						[delegate keyClicked: prevChar[0] = 'K'];	[delegate keyClicked: prevChar[1] = 'I'];	break;
					case Key_4:
						[delegate keyClicked: prevChar[0] = 'T'];	[delegate keyClicked: prevChar[1] = 'U'];	break;
				}
				break;
			case 7:	// 2
				switch (pressedKey)
				{
					case Key_1:
						[delegate keyClicked: prevChar[0] = 'E'];	break;
					case Key_2:
						[delegate keyClicked: prevChar[0] = 'K'];	[delegate keyClicked: prevChar[1] = 'A'];	break;
					case Key_3:
						[delegate keyClicked: prevChar[0] = 'S'];	[delegate keyClicked: prevChar[1] = 'I'];	break;
					case Key_5:
						[delegate keyClicked: prevChar[0] = 'N'];	[delegate keyClicked: prevChar[1] = 'A'];	break;
				}
				break;
			case 8:	// 3
				switch (pressedKey)
				{
					case Key_2:
						[delegate keyClicked: prevChar[0] = 'K'];	[delegate keyClicked: prevChar[1] = 'E'];	break;
					case Key_3:
						[delegate keyClicked: prevChar[0] = 'S'];	[delegate keyClicked: prevChar[1] = 'A'];	break;
					case Key_6:
						[delegate keyClicked: prevChar[0] = 'H'];	[delegate keyClicked: prevChar[1] = 'U'];	break;
				}
				break;
			case 9:
				switch (pressedKey)
				{
					case Key_3:
						[delegate keyClicked: prevChar[0] = 'S'];	[delegate keyClicked: prevChar[1] = 'E'];	break;
				}
				break;
			case 10:
				switch (pressedKey)
				{
					case Key_4:
						[delegate keyClicked: prevChar[0] = 'T'];	[delegate keyClicked: prevChar[1] = 'I'];	break;
				}
				break;
			case 11:	// 4
				switch (pressedKey)
				{
					case Key_1:
						[delegate keyClicked: prevChar[0] = 'O'];	break;
					case Key_4:
						[delegate keyClicked: prevChar[0] = 'T'];	[delegate keyClicked: prevChar[1] = 'A'];	break;
					case Key_5:
						[delegate keyClicked: prevChar[0] = 'N'];	[delegate keyClicked: prevChar[1] = 'I'];	break;
					case Key_7:
						[delegate keyClicked: prevChar[0] = 'M'];	[delegate keyClicked: prevChar[1] = 'U'];	break;
				}
				break;
			case 12:	// 5
				switch (pressedKey)
				{
					case Key_2:
						[delegate keyClicked: prevChar[0] = 'K'];	[delegate keyClicked: prevChar[1] = 'O'];	break;
					case Key_4:
						[delegate keyClicked: prevChar[0] = 'T'];	[delegate keyClicked: prevChar[1] = 'E'];	break;
					case Key_5:
						[delegate keyClicked: prevChar[0] = 'N'];	[delegate keyClicked: prevChar[1] = 'A'];	break;
					case Key_6:
						[delegate keyClicked: prevChar[0] = 'H'];	[delegate keyClicked: prevChar[1] = 'I'];	break;
					case Key_8:
						[delegate keyClicked: prevChar[0] = 'Y'];	[delegate keyClicked: prevChar[1] = 'U'];	break;
				}
				break;
			case 13:	// 6
				switch (pressedKey)
				{
					case Key_3:
						[delegate keyClicked: prevChar[0] = 'S'];	[delegate keyClicked: prevChar[1] = 'O'];	break;
					case Key_5:
						[delegate keyClicked: prevChar[0] = 'N'];	[delegate keyClicked: prevChar[1] = 'E'];	break;
					case Key_6:
						[delegate keyClicked: prevChar[0] = 'H'];	[delegate keyClicked: prevChar[1] = 'A'];	break;
					case Key_9:
						[delegate keyClicked: prevChar[0] = 'R'];	[delegate keyClicked: prevChar[1] = 'U'];	break;
				}
				break;
			case 14:
				switch (pressedKey)
				{
					case Key_6:
						[delegate keyClicked: prevChar[0] = 'H'];	[delegate keyClicked: prevChar[1] = 'E'];	break;
				}
				break;
			case 15:	// 123/かな
				switch (pressedKey)
				{
					case Key_7:
						[delegate keyClicked: prevChar[0] = 'M'];	[delegate keyClicked: prevChar[1] = 'I'];	break;
				}
				break;
			case 16:	// 7
				switch (pressedKey)
				{
					case Key_4:
						[delegate keyClicked: prevChar[0] = 'T'];	[delegate keyClicked: prevChar[1] = 'O'];	break;
					case Key_7:
						[delegate keyClicked: prevChar[0] = 'M'];	[delegate keyClicked: prevChar[1] = 'A'];	break;
					case Key_8:
						break;
					case Key_Asterisk:
						break;
				}
				break;
			case 17:	// 8
				switch (pressedKey)
				{
					case Key_5:
						[delegate keyClicked: prevChar[0] = 'N'];	[delegate keyClicked: prevChar[1] = 'O'];	break;
					case Key_7:
						[delegate keyClicked: prevChar[0] = 'M'];	[delegate keyClicked: prevChar[1] = 'E'];	break;
					case Key_8:
						[delegate keyClicked: prevChar[0] = 'Y'];	[delegate keyClicked: prevChar[1] = 'A'];	break;
					case Key_9:
						[delegate keyClicked: prevChar[0] = 'R'];	[delegate keyClicked: prevChar[1] = 'I'];	break;
					case Key_0:
						[delegate keyClicked: VK_OEM_MINUS];	break;
				}
				break;
			case 18:	// 9
				switch (pressedKey)
				{
					case Key_6:
						[delegate keyClicked: prevChar[0] = 'H'];	[delegate keyClicked: prevChar[1] = 'O'];	break;
					case Key_8:
						break;
					case Key_9:
						[delegate keyClicked: prevChar[0] = 'R'];	[delegate keyClicked: prevChar[1] = 'A'];	break;
					case Key_Sharp:
						[delegate keyPressed: VK_SHIFT];
						[delegate keyClicked: VK_OEM_2];
						[delegate keyReleased: VK_SHIFT];
						break;
				}
				break;
			case 19:
				switch (pressedKey)
				{
					case Key_9:
						[delegate keyClicked: prevChar[0] = 'R'];	[delegate keyClicked: prevChar[1] = 'E'];	break;
				}
				break;
			case 20:	// 変換
				switch (pressedKey)
				{
					case Key_Asterisk:	// 濁点
						switch (prevChar[0])
						{
							case 'K':
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = 'G'];	[delegate keyClicked: prevChar[1]];	break;
							case 'S':
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = 'Z'];	[delegate keyClicked: prevChar[1]];	break;
							case 'T':
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = 'D'];	[delegate keyClicked: prevChar[1]];	break;
							case 'H':
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = 'B'];	[delegate keyClicked: prevChar[1]];	break;
							case 'G':
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = 'K'];	[delegate keyClicked: prevChar[1]];	break;
							case 'Z':
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = 'S'];	[delegate keyClicked: prevChar[1]];	break;
							case 'D':
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = 'T'];	[delegate keyClicked: prevChar[1]];	break;
							case 'B':
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = 'H'];	[delegate keyClicked: prevChar[1]];	break;
						}
						break;
				}
				break;
			case 21:	// *
				switch (pressedKey)
				{
					case Key_7:
						[delegate keyClicked: prevChar[0] = 'M'];	[delegate keyClicked: prevChar[1] = 'O'];	break;
					case Key_Asterisk:	// 拗音
						switch (prevChar[0])
						{
							case 'X':	// 拗音 -> 通常文字
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = prevChar[1]];
								[delegate keyClicked: prevChar[1] = prevChar[2]];
								break;
							case 'A':
							case 'I':
							case 'U':
							case 'E':
							case 'O':
								[delegate keyClicked: VK_BACK];
								prevChar[1] = prevChar[0];
								[delegate keyClicked: prevChar[0] = 'X'];	[delegate keyClicked: prevChar[1]];
								break;
							case 'T':
							{
								if (prevChar[1] == 'U')
								{
									[delegate keyClicked: VK_BACK];
									prevChar[2] = prevChar[1];
									prevChar[1] = prevChar[0];
									[delegate keyClicked: prevChar[0] = 'X'];	[delegate keyClicked: prevChar[1]];	[delegate keyClicked: prevChar[2]];	break;
								}
								break;
							}
							case 'Y':
								[delegate keyClicked: VK_BACK];
								prevChar[2] = prevChar[1];
								prevChar[1] = prevChar[0];
								[delegate keyClicked: prevChar[0] = 'X'];	[delegate keyClicked: prevChar[1]];	[delegate keyClicked: prevChar[2]];	break;
								break;
						}
						break;
					case Key_0:
						[delegate keyClicked: prevChar[0] = 'W'];	[delegate keyClicked: prevChar[1] = 'O'];	break;
				}
				break;
			case 22:	// 0
				switch (pressedKey)
				{
					case Key_8:
						[delegate keyClicked: prevChar[0] = 'Y'];	[delegate keyClicked: prevChar[1] = 'O'];	break;
					case Key_Asterisk:
						switch (prevChar[0])
						{
							case 'H':
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = 'P'];	[delegate keyClicked: prevChar[1]];	break;
							case 'P':
								[delegate keyClicked: VK_BACK];
								[delegate keyClicked: prevChar[0] = 'H'];	[delegate keyClicked: prevChar[1]];	break;
						}
						break;
					case Key_0:
						[delegate keyClicked: prevChar[0] = 'W'];	[delegate keyClicked: prevChar[1] = 'A'];	break;
					case Key_Sharp:
						[delegate keyPressed: VK_SHIFT];
						[delegate keyClicked: '1'];
						[delegate keyReleased: VK_SHIFT];
						break;
				}
				break;
			case 23:	// #
				switch (pressedKey)
				{
					case Key_9:
						[delegate keyClicked: prevChar[0] = 'R'];	[delegate keyClicked: prevChar[1] = 'O'];	break;
					case Key_0:
						[delegate keyClicked: prevChar[0] = 'N'];	[delegate keyClicked: prevChar[1] = 'N'];	break;
					case Key_Sharp:
						[delegate keyClicked: VK_OEM_COMMA];	break;
				}
				break;
			case 24:
				switch (pressedKey)
				{
					case Key_Sharp:
						[delegate keyClicked: VK_OEM_PERIOD];	break;
				}
				break;
		}
		
		[self setImage: panelKana];
	}
}

- (BOOL)canHandleGestures
{
	return YES;
}

- (void)gestureStarted: (GSEventRef)event
{
	gesStart1 = GSEventGetInnerMostPathPosition(event);
	gesStart2 = GSEventGetInnerMostPathPosition(event);
	gesStartTime = gettimeofday_sec();
	
	// クリック発生前ならドラッグ開始
	if (rightClickTimer && [rightClickTimer isValid])
	{
		[rightClickTimer invalidate];
		
		[delegate mouseRightButtonPress];
		rightDragging = YES;
	}
	
	prevP1 = gesStart1;
	prevP2 = gesStart2;
}

- (void)gestureEnded: (GSEventRef)event
{
	gesEnd1 = GSEventGetInnerMostPathPosition(event);
	gesEnd2 = GSEventGetInnerMostPathPosition(event);
	
	// 右ドラッグ中ならリリース
	if (rightDragging)
	{
		[delegate mouseRightButtonRelease];
		rightDragging = NO;
		return;
	}
	
	if (diffLength(&gesStart1, &gesEnd1) < SAME_POINT_MARGIN && diffLength(&gesStart2, &gesEnd2) < SAME_POINT_MARGIN && (gettimeofday_sec() - gesStartTime) < (CLICK_INTERVAL / 1000.0))
	{
		[rightClickTimer release];
		rightClickTimer = [NSTimer scheduledTimerWithTimeInterval: (CLICK_TIMEOUT / 1000.0) target: self selector: @selector(sendMouseRightButtonClick:) userInfo: nil repeats: NO];
		[rightClickTimer retain];
	}
}

- (void)gestureChanged: (GSEventRef)event
{
	CGSize screen = [UIHardware fullScreenApplicationContentRect].size;
	
	CGPoint p1 = GSEventGetInnerMostPathPosition(event);
	CGPoint p2 = GSEventGetInnerMostPathPosition(event);
	
	int x = (int)(p1.x / screen.width * USHRT_MAX);
	int y = (int)(p1.y / screen.height * USHRT_MAX);
	
	if (rightDragging)
	{
		[delegate mouseMoveAbsolute: CGPointMake(x, y)];
		[delegate mouseMoveRelative: CGPointMake(p1.x - prevP1.x, p1.y - prevP1.y)];
	}
	else	// scroll
	{
		// 1でも2でも同じ動作?
		if (1 < (p1.y - prevP1.y) || 1 < (prevP1.x - p1.x))
			[delegate mouseWheel: -1];
		else if (1 < (prevP1.y - p1.y) || 1 < (p1.x - prevP1.x))
			[delegate mouseWheel: 1];
	}
	
	prevP1 = p1;
	prevP2 = p2;
}

- (void)sendMouseLeftButtonClick: (NSTimer *)timer
{
	[delegate mouseLeftButtonClick];
}

- (void)sendMouseRightButtonClick: (NSTimer *)timer
{
	[delegate mouseRightButtonClick];
}

/*
	userInfoが使えない?
*/
- (void)showPanel: (NSTimer *)timer
{
	UIImage *panel = nil;
	if (currentMode == Mode_Num)
	{
		switch (pressedKey)
		{
			case Key_0:	panel = panelNum0;	break;
			case Key_1:	panel = panelNum1;	break;
			case Key_2:	panel = panelNum2;	break;
			case Key_3:	panel = panelNum3;	break;
			case Key_4:	panel = panelNum4;	break;
			case Key_5:	panel = panelNum5;	break;
			case Key_6:	panel = panelNum6;	break;
			case Key_7:	panel = panelNum7;	break;
			case Key_8:	panel = panelNum8;	break;
			case Key_9:	panel = panelNum9;	break;
			case Key_Asterisk:	panel = panelNumAsterisk;	break;
			case Key_Sharp:	panel = panelNumSharp;	break;
		}
	}
	else if (currentMode == Mode_Kana)
	{
		switch (pressedKey)
		{
			case Key_0:	panel = panelKana0;	break;
			case Key_1:	panel = panelKana1;	break;
			case Key_2:	panel = panelKana2;	break;
			case Key_3:	panel = panelKana3;	break;
			case Key_4:	panel = panelKana4;	break;
			case Key_5:	panel = panelKana5;	break;
			case Key_6:	panel = panelKana6;	break;
			case Key_7:	panel = panelKana7;	break;
			case Key_8:	panel = panelKana8;	break;
			case Key_9:	panel = panelKana9;	break;
			case Key_Asterisk:	panel = panelKanaAsterisk;	break;
			case Key_Sharp:	panel = panelKanaSharp;	break;
		}
	}
	
	if (panel != nil)
		[self setImage: panel];
}

@end
